/*
 * The UserServiceBean.java created for spikeCASservice projects. 
 */
package com.google.code.sip.ucenter.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.google.code.sip.core.dao.Page;
import com.google.code.sip.core.service.ServiceException;
import com.google.code.sip.ucenter.dao.RoleDao;
import com.google.code.sip.ucenter.dao.UserCountDao;
import com.google.code.sip.ucenter.dao.mongo.PasswordActionDaoImpl;
import com.google.code.sip.ucenter.dao.mongo.UserCustomProfileDaoImpl;
import com.google.code.sip.ucenter.dao.mongo.UserDaoImpl;
import com.google.code.sip.ucenter.dao.mongo.UserEventDaoImpl;
import com.google.code.sip.ucenter.dao.mongo.UserProfileDaoImpl;
import com.google.code.sip.ucenter.mail.DefaultMailService;
import com.google.code.sip.ucenter.mail.MailServiceThread;
import com.google.code.sip.ucenter.model.ResetPasswordEvent;
import com.google.code.sip.ucenter.model.Role;
import com.google.code.sip.ucenter.model.User;
import com.google.code.sip.ucenter.model.UserCount;
import com.google.code.sip.ucenter.model.UserCustomProfile;
import com.google.code.sip.ucenter.model.UserEvent;
import com.google.code.sip.ucenter.model.UserProfile;
import com.google.code.sip.ucenter.service.UserManager;
import com.google.code.sip.ucenter.utils.StringRegexUtils;

/**
 * Describes the <tt>UserServiceBean</tt> object's responsibility,
 * collaboration, relationship and usage.
 * 
 * @author Steven Liu
 * @version 1.0 2010-5-31
 */
public class UserManagerImpl implements UserManager {
	private static Logger logger = LoggerFactory
			.getLogger(UserManagerImpl.class);

	private String resetPasswordUrl = null;

	@Autowired
	private UserDaoImpl userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private UserProfileDaoImpl userProfileDao;
	@Autowired
	private UserCustomProfileDaoImpl userCustomProfileDao;
	@Autowired
	private UserEventDaoImpl userEventDao;
	@Autowired
	private UserCountDao userCountDao;
	@Autowired
	private PasswordEncoder passwordEncoder;
	@Autowired
	private DefaultMailService mailService;
	@Autowired
	private FreeMarkerConfigurer mailTemplateEngine;

	@Autowired
	private PasswordActionDaoImpl resetPasswordDao;

	@Override
	public User getUser(String id) {
		return userDao.get(id);
	}

	@Override
	public void saveUser(User user) {
		if (user.isNew()) {
			user.setPassword(encodePassword(user.getPassword()));
		}
		user.setLatestUpdatedDate(new Date());
		userDao.save(user);
	}

	@Override
	public User getUserByName(String username) {
		return userDao.getByName(username);
	}

	@Override
	public User getUserByHuoshowId(String huoshowId) {
		return userDao.getByHuoshowId(huoshowId);
	}

	@Override
	public User getUserByEmail(String email) {
		return userDao.getByEmail(email);
	}

	@Override
	public void deleteUser(String id) {
		User user = userDao.get(id);
		if (user != null) {
			deleteUser(user);
		}
	}

	@Override
	public void deleteUser(User user) {
		deleteUser(user, false);
	}

	@Override
	public void deleteUser(User user, boolean totally) {
		if (user.isBuildin()) {// 不能删除系统内置用户
			logger.warn("不能删除系统内置用户" + user.getUsername() + "。");
			throw new ServiceException("不能删除系统内置用户" + user.getUsername() + "。");
		}
		if (totally) {// 彻底删除
			userDao.delete(user);
			// 删除相关实体
			userProfileDao.delete("user", user);
			userCustomProfileDao.delete("user", user);
		} else {// 打删除标记
			user.setDeleted(true);
			user.setDeletedDate(new Date());
			userDao.save(user);
		}
	}

	@Override
	public void setPassword(String id, String password) {
		User user = getUser(id);
		if (user != null) {
			user.setPassword(encodePassword(password));
			userDao.save(user);
		}
	}

	@Override
	public void setPasswordByName(String username, String password) {
		User user = getUserByName(username);
		if (user != null) {
			user.setPassword(encodePassword(password));
			userDao.save(user);
		}
	}

	@Override
	public boolean login(String username, String password) {
		User user = null;
		if (StringRegexUtils.isEmail(username)) {
			user = getUserByEmail(username);
		} else {
			user = getUserByName(username);
			// 根据火秀号查用户
			if (user == null) {
				user = getUserByHuoshowId(username);
			}
		}
		if (user == null) {
			return false;
		}
		if (!user.isEnabled() || user.isLocked() || user.isDeleted()) {// 如用户被禁止、锁定、删除，返回false;
			return false;
		}
		boolean matched = encodePassword(password).equals(user.getPassword());
		if (matched) {
			user.setLatestLoginDate(new Date());
			return true;
		}
		return false;
	}

	@Override
	public int getCreditCount(User user) {
		if (user != null) {
			UserCount userCount = userCountDao.getByUser(user);
			if (userCount != null) {
				return userCount.getCreditCount();
			} else {
				return 0;
			}
		}
		return 0;
	}

	@Override
	public List<UserCount> getCreditCount(List<User> users) {
		if (users != null && !users.isEmpty()) {
			return userCountDao.getByUsers(users);
		}
		return null;
	}

	@Override
	public void findUser(Page<User> page) {
		// 过滤已删除的用户
		page.getFilters().put("deleted", false);
		userDao.findByPage(page);
	}

	private String encodePassword(String password) {
		return passwordEncoder.encodePassword(password, null);
	}

	@Override
	public long countUser() {
		return userDao.count();
	}

	@Override
	public boolean changePassword(String username, String oldPassword,
			String newPassword) {
		User user = getUserByName(username);
		if (user == null) {
			return false;
		}
		String encodedOldPassword = encodePassword(oldPassword);
		if (!user.getPassword().equals(encodedOldPassword)) {
			return false;
		}
		user.setPassword(encodePassword(newPassword));
		userDao.save(user);
		return true;
	}

	@Override
	public List<User> findUser(String propName, String propValue) {
		return userDao.findByProperty(propName, propValue);
	}

	@Override
	public UserProfile getProfile(String userId) {
		User user = this.getUser(userId);
		if (user != null) {
			return getProfile(user);
		} else {
			return null;
		}
	}

	@Override
	public UserProfile getProfile(User user) {
		return userProfileDao.getByUser(user);
	}

	@Override
	public UserCustomProfile getUserCustomProfile(User user, String propName) {
		return userCustomProfileDao.get(user, propName);
	}

	@Override
	public UserCustomProfile getUserCustomProfile(String userId, String propName) {
		User user = this.getUser(userId);
		if (user == null) {
			return null;
		}
		return getUserCustomProfile(user, propName);
	}

	@Override
	public List<UserCustomProfile> getUserCustomProfiles(User user) {
		return userCustomProfileDao.findByUser(user);
	}

	@Override
	public List<UserCustomProfile> getUserCustomProfiles(String userId) {
		User user = this.getUser(userId);
		if (user == null) {
			return null;
		}
		return getUserCustomProfiles(user);
	}

	@Override
	public void saveUserCustomProfile(UserCustomProfile customProfile) {
		userCustomProfileDao.save(customProfile);
	}

	@Override
	public void saveUserProfile(UserProfile profile) {
		userProfileDao.save(profile);

	}

	@Override
	public void startResetPassword(User user) {
		String newPassword = RandomStringUtils.randomAlphanumeric(6);
		String email = user.getEmail();
		String username = user.getUsername();
		// 发送注册成功邮件
		SimpleMailMessage msg = new SimpleMailMessage();
		msg.setTo(email);
		msg.setSubject("找回密码");
		msg.setFrom("webmaster@huoshow.com");
		Map<String, Object> model = new HashMap<String, Object>();
		String time = "" + new Date().getTime();
		model.put("time", time);
		model.put("uid", username);
		model.put("password", newPassword);
		model.put("websiteUrl", resetPasswordUrl);
		mailService.setMailTemplateEngine(mailTemplateEngine);

		new MailServiceThread(mailService, "resetPassword.ftl", msg, model)
				.start();
		// 保存密码激活对象
		ResetPasswordEvent event = new ResetPasswordEvent();
		event.setEmail(email);
		event.setPassword(newPassword);
		event.setUsername(username);
		resetPasswordDao.save(event);
	}

	@Override
	public void saveUserEvent(UserEvent userEvent) {
		userEventDao.save(userEvent);

	}

	@Override
	public void resetPassword(String userId, String newPassword) {
		User user = getUser(userId);
		if (user != null) {
			user.setPassword(encodePassword(newPassword));
			userDao.save(user);
		}

	}

	@Override
	public void findAdminUser(Page<User> page) {
		Role adminRole = roleDao.getByName(Role.ADMIN);
		page.addFilter("role", adminRole);
		userDao.findByPage(page);
	}

	@Override
	public void findNormalUser(Page<User> page) {
		Role normalRole = roleDao.getByName(Role.NORMAL);
		page.addFilter("role", normalRole);
		userDao.findByPage(page);
	}

	/**
	 * @return the resetPasswordUrl
	 */
	public String getResetPasswordUrl() {
		return resetPasswordUrl;
	}

	/**
	 * @param resetPasswordUrl
	 *            the resetPasswordUrl to set
	 */
	public void setResetPasswordUrl(String resetPasswordUrl) {
		this.resetPasswordUrl = resetPasswordUrl;
	}

	@Override
	public User getUser(String username, String email, String huoshowId) {
		return userDao.getUser(username, email, huoshowId);
	}

}
